<?php
/**
 * Created by 项目.
 * User: xuguopeng
 * Date: 2020-01-07
 * Time: 15:51
 */

namespace app\api\service;


use app\api\model\WxMenu;
use app\api\model\WxMenus;
use app\lib\exception\TokenException;
use app\lib\exception\WeChatException;
use think\facade\Cache;

class Menu
{
    private $wxAppId;
    private $wxAppSecret;
    private $wxAccessUrl;
    private $wxMenuUrl;

    function __construct()
    {
        header("Content-Type: text/html;charset=utf-8");
        $this->wxAppId = config('wechat.app_id');
        $this->wxAppSecret = config('wechat.app_secret');
        $this->wxAccessUrl = sprintf(config('wechat.token_url'),
            $this->wxAppId,$this->wxAppSecret);
    }

    public function get()
    {
        return $this->createMenus();
    }

    //创建自定义菜单
    private function createMenus()
    {
        $menujsons = $this->getMenusJson();
        $token = Cache::get('wechat_access_token');
        if(!$token)
        {
            $access_token = $this->getAccessToken();
        }
        else{
            $access_token = $token;
        }
        $this->wxMenuUrl = sprintf(config('wechat.menu_url'),
            $access_token);
        return json_decode(https_post($this->wxMenuUrl,$menujsons),true);
    }

    //获取自定义菜单的json数据
    private function getMenusJson()
    {
        //三个底部菜单
        $caidan1 = WxMenu::get(1);
        $caidan2 = WxMenu::get(2);
        $caidan3 = WxMenu::get(3);
        $zacaidan11 = array();
        $zacaidan22 = array();
        $zacaidan33 = array();
        $menus = array();
        //菜单一
        if($caidan1['name'] == '')
        {
            $menu1 = WxMenus::where('tid','=',1)->where('open','=',1)->find();
            if($menu1)
            {
                $zacaidan11['type'] = $menu1['type'];
                $zacaidan11['name'] = $menu1['name'];
                if($menu1['type'] == "click"){
                    $zacaidan11['key'] = $menu1['typevalue'];
                }elseif ($menu1['type'] == "view"){
                    $zacaidan11['url'] = $menu1['typevalue'];
                }else{
                    $zacaidan11['url'] = $menu1['typevalue'];
                    $zacaidan11['pagepath'] = $menu1['typevalue'];
                    $zacaidan11['appid'] = config('wx.app_id');
                }
            }
        }
        else{
            $zacaidan1 = array();
            $menu1 =WxMenus::where('tid','=',1)->where('open','=',1)->select();
            if(!$menu1->isEmpty())
            {
                $menu1 = $menu1->toArray();
                foreach($menu1 as $v)
                {
                    if($v['type'] == "click")
                    {
                        $arr = array('name'=>$v['name'],'type'=>$v['type'],'key'=>$v['typevalue']);
                    }
                    elseif($v['type'] == "view") {
                        $arr = array('name'=>$v['name'],'type'=>$v['type'],'url'=>$v['typevalue']);
                    }
                    else {
                        $arr = array( 'name'=>$v['name'],'type'=>$v['type'],'pagepath'=>$v['typevalue'], 'appid' => config('wx.app_id'), 'url'=>$v['typevalue']);
                    }
                    array_push($zacaidan1, $arr);
                }
                $zacaidan11['name'] = $caidan1['name'];
                $zacaidan11['sub_button'] = $zacaidan1;
            }
        }
        //菜单二
        if($caidan2['name'] == '')
        {
            $menu2 = WxMenus::where('tid','=',2)->where('open','=',1)->find();
            if($menu2)
            {
                $zacaidan22['type'] = $menu2['type'];
                $zacaidan22['name'] = $menu2['name'];
                if($menu2['type'] == "click"){
                    $zacaidan22['key'] = $menu2['typevalue'];
                }elseif ($menu2['type'] == "view"){
                    $zacaidan22['url'] = $menu2['typevalue'];
                }else{
                    $zacaidan22['url'] = $menu2['typevalue'];
                    $zacaidan22['pagepath'] = $menu2['typevalue'];
                    $zacaidan22['appid'] = config('wx.app_id');
                }
            }
        }
        else{
            $zacaidan2 = array();
            $menu2 = WxMenus::where('tid','=',2)->where('open','=',1)->select();
            if(!$menu2->isEmpty())
            {
                $menu2 = $menu2->toArray();
                foreach($menu2 as $v)
                {
                    if($v['type'] == "click")
                    {
                        $arr = array('name'=>$v['name'],'type'=>$v['type'],'key'=>$v['typevalue']);
                    }
                    elseif($v['type'] == "view") {
                        $arr = array('name'=>$v['name'],'type'=>$v['type'],'url'=>$v['typevalue']);
                    }
                    else {
                        $arr = array( 'name'=>$v['name'],'type'=>$v['type'],'pagepath'=>$v['typevalue'], 'appid' => config('wx.app_id'), 'url'=>$v['typevalue']);
                    }
                    array_push($zacaidan2, $arr);
                }
                $zacaidan22['name'] = $caidan2['name'];
                $zacaidan22['sub_button'] = $zacaidan2;
            }
        }
        //菜单三
        if($caidan3['name'] == '')
        {
            $menu3 = WxMenus::where('tid','=',3)->where('open','=',1)->find();
            if($menu3)
            {
                $zacaidan33['type'] = $menu3['type'];
                $zacaidan33['name'] = $menu3['name'];
                if($menu3['type'] == "click"){
                    $zacaidan33['key'] = $menu3['typevalue'];
                }elseif ($menu3['type'] == "view"){
                    $zacaidan33['url'] = $menu3['typevalue'];
                }else{
                    $zacaidan33['url'] = $menu3['typevalue'];
                    $zacaidan33['pagepath'] = $menu3['typevalue'];
                    $zacaidan33['appid'] = config('wx.app_id');
                }
            }
        }
        else{
            $zacaidan3 = array();
            $menu3 = WxMenus::where('tid','=',3)->where('open','=',1)->select();
            if(!$menu3->isEmpty())
            {
                $menu3 = $menu3->toArray();
                foreach($menu3 as $v)
                {
                    if($v['type'] == "click")
                    {
                        $arr = array('name'=>$v['name'],'type'=>$v['type'],'key'=>$v['typevalue']);
                    }
                    elseif($v['type'] == "view") {
                        $arr = array('name'=>$v['name'],'type'=>$v['type'],'url'=>$v['typevalue']);
                    }
                    else {
                        $arr = array( 'name'=>$v['name'],'type'=>$v['type'],'pagepath'=>$v['typevalue'], 'appid' => config('wx.app_id'), 'url'=>$v['typevalue']);
                    }
                    array_push($zacaidan3, $arr);
                }
                $zacaidan33['name'] = $caidan3['name'];
                $zacaidan33['sub_button'] = $zacaidan3;
            }
        }
        if($zacaidan11 && $zacaidan22 && $zacaidan33)
        {
            $menus=array(
                'button' => array(
                    $zacaidan11,$zacaidan22,$zacaidan33
                )
            );
        }
        elseif($zacaidan11 && $zacaidan22 && !$zacaidan33){
            $menus=array(
                'button' => array(
                    $zacaidan11,$zacaidan22
                )
            );
        }
        elseif(!$zacaidan11 && $zacaidan22 && $zacaidan33){
            $menus=array(
                'button' => array(
                    $zacaidan22,$zacaidan33
                )
            );
        }
        elseif($zacaidan11 && !$zacaidan22 && $zacaidan33){
            $menus=array(
                'button' => array(
                    $zacaidan11,$zacaidan33
                )
            );
        }
        elseif($zacaidan11 && !$zacaidan22 && !$zacaidan33){
            $menus=array(
                'button' => array(
                    $zacaidan11
                )
            );
        }
        elseif(!$zacaidan11 && $zacaidan22 && !$zacaidan33){
            $menus=array(
                'button' => array(
                    $zacaidan22
                )
            );
        }
        elseif(!$zacaidan11 && !$zacaidan22 && $zacaidan33){
            $menus=array(
                'button' => array(
                    $zacaidan33
                )
            );
        }
        $this->arrayRecursive($menus, 'urlencode', true);
        $json = json_encode($menus);
        return urldecode($json);
    }
    /**************************************************************
     *
     *    使用特定function对数组中所有元素做处理
     *    @param  string  &$array     要处理的字符串
     *    @param  string  $function   要执行的函数
     *    @return boolean $apply_to_keys_also     是否也应用到key上
     *    @access public
     *
     *************************************************************/
    private function arrayRecursive(&$array, $function, $apply_to_keys_also = false)
    {
        static $recursive_counter = 0;
        if (++$recursive_counter > 1000) {
            die('possible deep recursion attack');
        }
        foreach ($array as $key => $value) {
            if (is_array($value)) {
                $this->arrayRecursive($array[$key], $function, $apply_to_keys_also);
            } else {
                $array[$key] = $function($value);
            }

            if ($apply_to_keys_also && is_string($key)) {
                $new_key = $function($key);
                if ($new_key != $key) {
                    $array[$new_key] = $array[$key];
                    unset($array[$key]);
                }
            }
        }
        $recursive_counter--;
    }

    /**
     * @param $openid
     * 获取accessToken
     */
    private function getAccessToken()
    {
        $wxResult = curl_get($this->wxAccessUrl);
        if(empty($wxResult))
        {
            throw new Exception('获取access_token时异常,微信内部错误');
        }
        else{
            $loginFail = array_key_exists('errcode',$wxResult);
            if($loginFail)
            {
                $this->processLoginError($wxResult);
            }
            else{
                $expire_in = config('setting.access_token_expire_in');
                $result = cache('wechat_access_token',$wxResult['access_token'],$expire_in);
                if(!$result)
                {
                    throw new TokenException([
                        'msg' => '服务器缓存异常',
                        'errorCode' => 10005
                    ]);
                }
                return $wxResult['access_token'];
            }
        }
    }
    /**
     * @param $wxResult 微信返回信息
     * @throws WeChatException 微信公用返回错误信息类
     */
    private function processLoginError($wxResult)
    {
        throw new WeChatException([
            'msg' => $wxResult['errmsg'],
            'errorCode' => $wxResult['errcode']
        ]);
    }
}